#ifndef __WIZ_DATATYPE_BIMAP_HPP__SHANHAOBO_19800429__
#define __WIZ_DATATYPE_BIMAP_HPP__SHANHAOBO_19800429__

#include "./WizDataTypeMap.hpp"
#include "./WizDataTypeSet.hpp"

namespace Wiz
{
    namespace BiMap
    {
        template<class LftValT, class RtValT>
        class Type
        {
            template<class T>
            struct ComparePtr
            {
                ::Wiz::Bool::Type operator()(const T& Lft, const T& Rt) const
                {
                    return *Lft < *Rt;
                }
            };

            typedef ::Wiz::Map::Type<LftValT, RtValT>                                             LeftToRightMap;
            typedef ::Wiz::Map::Type<const RtValT*, const LftValT*, ComparePtr<const RtValT*>>    RightToLeftMap;

            LeftToRightMap  m_LeftToRightMap;
            RightToLeftMap  m_RightToLeftMap;
        public:
            Type(){}
            ~Type(){}
        public:
            ::Wiz::Bool::Type Insert(LftValT Lft, RtValT Rt)
            {
                LeftToRightMap::tIterator LTRItr = m_LeftToRightMap.Find(Lft);
                if (LTRItr != m_LeftToRightMap.End())
                {
                    return ::Wiz::Bool::False;
                }

                RightToLeftMap::tIterator RTLItr = m_RightToLeftMap.Find(&Rt);
                if (RTLItr != m_RightToLeftMap.End())
                {
                    return ::Wiz::Bool::False;
                }

                LTRItr = m_LeftToRightMap.Insert(Lft, Rt);

                m_RightToLeftMap.Insert(&(LTRItr.GetValue()), &(LTRItr.GetIndex()));

                return ::Wiz::Bool::True;
            }

        public:
            ::Wiz::Bool::Type FindRight(const LftValT& Lft, RtValT& Rt)
            {
                LeftToRightMap::tIterator LTRItr = m_LeftToRightMap.Find(Lft);
                if (LTRItr == m_LeftToRightMap.End())
                {
                    return ::Wiz::Bool::False;
                }

                Rt = LTRItr.GetValue();
                return ::Wiz::Bool::True;
            }
            ::Wiz::Bool::Type FindLeft(const RtValT& Rt, LftValT& Lft)
            {
                RightToLeftMap::tIterator RTLItr = m_RightToLeftMap.Find(&Rt);
                if (RTLItr == m_RightToLeftMap.End())
                {
                    return ::Wiz::Bool::False;
                }

                Lft = *(RTLItr.GetValue());
                return ::Wiz::Bool::True;
            }
        }; /// end of class Type
    } /// end of namespace BiMap
} /// end of namespace Wiz

#endif /*__WIZ_DATATYPE_BIMAP_HPP__SHANHAOBO_19800429__*/
